package com.mftour.moudles.aspect;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.mftour.common.Constant;
import com.mftour.common.utils.JsonUtil;
import com.mftour.moudles.entity.ConsoleLog;
import com.mftour.moudles.entity.User;
import com.mftour.moudles.service.ConsoleLogService;

@Aspect
public class SystemLogAspect {

	private final Logger logger = Logger.getLogger(SystemLogAspect.class);

	@Autowired
	private ConsoleLogService logSer;
	private long startTime;
	private Integer logId;

	private final String BaseControllerMethod = "execution(void com.mftour.moudles.controller.BaseController.setReqAndRes(HttpServletRequest,HttpServletResponse))";

	@Pointcut(value = "execution(* com.mftour.moudles.service.impl.*.*(..))")
	public void servicePointcut() {
	}

	@Pointcut(value = "execution(* com.mftour.moudles.controller.*.*(..))")
	// @Pointcut(value="@annotation(org.springframework.web.bind.annotation.RequestMapping)")
	public void controllerPointcut() {

	}

	@Before("controllerPointcut()")
	public void before(JoinPoint joinPoint) {
		logId = 0;
		startTime = 0;
		if (checkPoint(joinPoint)) {
			return;
		}
		Object[] args = joinPoint.getArgs();

		// System.out.println(joinPoint.getKind());
		// System.out.println(joinPoint.getClass().getName());
		// System.out.println(joinPoint.toString());
		// System.out.println(joinPoint.getTarget().getClass().getName());
		// System.out.println(joinPoint.toShortString());

		// DynamicDataSourceHolder.setDataSourceType(DataSourceType.DKHDATASOURCE);
		System.out.println("before qieru");

		ServletRequestAttributes servletReq = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if (servletReq == null) {
			System.err.println("request null");
			return;
		}
		HttpServletRequest request = servletReq.getRequest();
		HttpSession session = request.getSession();
		// 读取session中的用户
		User user = (User) session.getAttribute(Constant.SESSION_LOGIN_USER);
		if (user == null) {
			user = new User();
			user.setUserId(-1);
			user.setUserName("还没有登录");
		}
		// 请求的IP
		String ip = request.getRemoteAddr();
		if (ip.equals("0:0:0:0:0:0:0:1")) {
			ip = "localhost";
		}
		try {
			// *========控制台输出=========*//
			System.out.println("=====前置通知开始=====");
			System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));

			System.out.println("请求人:" + user.getUserName());
			System.out.println("请求IP:" + ip);
			// *========数据库日志=========*//
			ConsoleLog consoleLog = new ConsoleLog();
			consoleLog.setOperatorId(user.getUserId().toString());
			consoleLog.setOperatorName(user.getUserName());
			if (user.getUserId().intValue() == -1) {
				consoleLog.setLogType((short) -1);
			} else {
				consoleLog.setLogType((short) 1);
			}
			consoleLog.setOperateMethod(getMethodName(joinPoint.toString()));
			String content = "";
			for (Object o : args) {
				content = content + "|" + JsonUtil.writeValueAsString(o);
			}
			consoleLog.setContent(content);
			logSer.insertSelective(consoleLog);
			logId = consoleLog.getId();
			startTime = new Date().getTime();
			System.err.println("=====前置通知结束=====");
		} catch (Exception e) {
			// 记录本地异常日志
			String errorMsg = getStackTraceMsg(e);
			logger.error("==前置通知异常==");
			logger.error("异常信息:{" + errorMsg + "}");
		}
	}

	public static String getStackTraceMsg(Exception e) {
		StringBuffer message = new StringBuffer();
		StackTraceElement[] exceptionStack = e.getStackTrace();
		message.append(e.toString());
		for (StackTraceElement ste : exceptionStack) {
			message.append("\n\tat " + ste);
		}
		return message.toString();
	}

	@After("controllerPointcut()")
	public void after(JoinPoint joinPoint) {
		if (checkPoint(joinPoint)) {
			return;
		}

		// System.out.println(joinPoint.getKind());
		// System.out.println(joinPoint.getClass().getName());
		// System.out.println(joinPoint.toString());
		// System.out.println(joinPoint.getTarget().getClass().getName());
		// System.out.println(joinPoint.toShortString());

		// DynamicDataSourceHolder.setDataSourceType(DataSourceType.DKHDATASOURCE);
		System.out.println("after qieru");

		if (logId.intValue() == 0) {
			System.err.println(getMethodName(joinPoint.toString()));
		} else {
			ConsoleLog consoleLog = new ConsoleLog();
			consoleLog.setId(logId);
			consoleLog.setOperateTime((int) (new Date().getTime() - startTime));
			logSer.updateByPrimaryKeySelective(consoleLog);
		}
	}

	private boolean checkPoint(JoinPoint joinPoint) {
		if (joinPoint.toString().equals(BaseControllerMethod) || joinPoint.getSignature().getName().equals("initBinder")) {
			return true;
		} else {
			return false;
		}
	}

	private String getMethodName(String methodName) {
		methodName = methodName.replace("execution(", "");
		methodName = methodName.replace("))", ")");
		return methodName;
	}
}
